﻿Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Drawing
Imports System.Workflow.ComponentModel.Compiler
Imports System.Workflow.ComponentModel.Serialization
Imports System.Workflow.ComponentModel
Imports System.Workflow.ComponentModel.Design
Imports System.Workflow.Runtime
Imports System.Workflow.Activities
Imports System.Workflow.Activities.Rules
Imports Microsoft.SharePoint.Workflow
Imports Microsoft.SharePoint.WorkflowActions

Public Class ResetCurrentVersion
    Inherits SequentialWorkflowActivity

    Public workflowProperties As New SPWorkflowActivationProperties
    Private ListItems As List(Of ListItem)
    Private Moderation As Boolean = False

    Public Sub New()
        MyBase.New()
        InitializeComponent()
        ListItems = New List(Of ListItem)
    End Sub

    ''' <summary>
    ''' Returns TRUE if versioning is enabled.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Terminates workflow if the list does not have versioning enabled.</remarks>
    Private Sub AreVersionsOn(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.ConditionalEventArgs)
        e.Result = workflowProperties.List.EnableVersioning
    End Sub

    ''' <summary>
    ''' Stores the binary of each version in a custom class.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub StoreVersions_Execute(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim sourceItem As SPListItem = workflowProperties.Item
        For index As Integer = sourceItem.Versions.Count - 1 To 0 Step -1
            Dim hashProperties As New Hashtable

            For Each sourceField As SPField In sourceItem.Fields
                Dim sourceVersion As SPListItemVersion = sourceItem.Versions(index)

                If Not sourceField.ReadOnlyField AndAlso Not sourceField.Type = SPFieldType.Attachments Then
                    hashProperties(sourceField.Title) = Convert.ToString(sourceVersion(sourceField.Title))
                ElseIf sourceField.Title = "Created" OrElse sourceField.Title = "Modified" Then
                    Dim sourceDate As DateTime = Convert.ToDateTime(sourceVersion(sourceField.Title))
                    hashProperties(sourceField.Title) = sourceItem.Web.RegionalSettings.TimeZone.UTCToLocalTime(sourceDate)
                ElseIf sourceField.Title = "Created By" OrElse sourceField.Title = "Modified By" Then
                    hashProperties(sourceField.Title) = Convert.ToString(sourceVersion(sourceField.Title))
                ElseIf index > 0 AndAlso sourceField.Title = "Check In Comment" Then
                    hashProperties(sourceField.Title) = sourceItem.File.Versions.GetVersionFromLabel(sourceItem.Versions(index).VersionLabel).CheckInComment
                ElseIf sourceField.Title = "Approver Comments" Then
                    hashProperties(sourceField.Title) = Convert.ToString(sourceVersion(sourceField.Title))
                End If
            Next

            Dim binary As Byte()
            If index = 0 Then
                binary = sourceItem.File.OpenBinary
                If sourceItem.Fields.ContainsField("Check In Comment") Then
                    hashProperties("Check In Comment") = sourceItem.File.CheckInComment
                End If
            Else
                binary = sourceItem.File.Versions.GetVersionFromLabel(sourceItem.Versions(index).VersionLabel).OpenBinary
            End If
            ListItems.Add(New ListItem(hashProperties, binary, Convert.ToDouble(sourceItem.Versions(index).VersionLabel), sourceItem.File.Name))
        Next
    End Sub

    ''' <summary>
    ''' Deletes the item from the list.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub RecycleItem_Execute(ByVal sender As System.Object, ByVal e As System.EventArgs)
        workflowProperties.Item.Recycle()
    End Sub

    ''' <summary>
    ''' Restores and resequences the versions to the list.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub RestoreVersions_Execute(ByVal sender As System.Object, ByVal e As System.EventArgs)


        Dim maxVersion = (From listItem In ListItems _
                               Select listItem.Version).Max.ToString.Split(CChar("."))(0)

        Dim minVersion = (From listItem In ListItems _
                                Select listItem.Version).Min.ToString.Split(CChar("."))(0)

        Dim qListItems = From l In ListItems _
                         Where l.Version.ToString.Split(CChar("."))(0) = maxVersion _
                         OrElse l.Version.ToString.Split(CChar("."))(0) = minVersion _
                         Order By l.Version Ascending _
                         Select l
        Dim id As Integer = -1
        For Each listItem In qListItems
            listItem.AddTo(workflowProperties.Web, workflowProperties.ListId, id)
        Next

    End Sub

    ''' <summary>
    ''' Enables moderation if not already enabled.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks>Moderation is required to properly update the modified date for major versions.</remarks>
    Private Sub EnableModeration_Execute(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Moderation = workflowProperties.List.EnableModeration
        If Not Moderation Then
            workflowProperties.List.EnableModeration = True
            workflowProperties.List.Update()
        End If
    End Sub

    ''' <summary>
    ''' Restores the lists's EnableModeration property.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub RestoreModeration_Execute(ByVal sender As System.Object, ByVal e As System.EventArgs)
        workflowProperties.Web.AllowUnsafeUpdates = True
        If Not Moderation = workflowProperties.List.EnableModeration Then
            Using mySite As New SPSite(workflowProperties.Web.Url)
                Using myWeb As SPWeb = mySite.OpenWeb
                    Dim list As SPList = myWeb.Lists.GetList(workflowProperties.ListId, False)
                    list.EnableModeration = Moderation
                    list.Update()
                End Using
            End Using
        End If
        workflowProperties.Web.AllowUnsafeUpdates = False
    End Sub

End Class